<template>
  <ProTable ref="tableRef" :fetchListApi="fetchListApi" :columns="columns">
    <template #toolbars>
      <b-button icon="add" @click="onAdd" code="system:user:add">新增</b-button>
    </template>
    <template #control="{ search, searchParams }">
      <DeptTree :search="search" :deptId="searchParams.deptId" />
    </template>
    <template #bodyCell="{ column, record }">
      <template v-if="column.dataIndex === 'operation'">
        <b-button
          icon="data-permission"
          type="link"
          code="system:user:query"
          @click="() => onSetDataPermission(record)"
          >数据权限</b-button
        >
        <b-button
          icon="edit"
          type="link"
          @click="() => onEdit(record)"
          code="system:user:edit"
          >编辑</b-button
        >
        <b-button
          icon="del"
          type="link"
          @click="() => onDelete(record)"
          code="system:user:remove"
          >删除</b-button
        >
        <b-button
          icon="reset"
          type="link"
          @click="() => onResetPassword(record)"
          code="system:user:resetPwd"
          >重置密码</b-button
        >
      </template>
      <template v-if="column.dataIndex === 'status'">
        <Switch
          :checked="record.status"
          checked-value="0"
          un-checked-value="1"
          @change="(checked) => onChangeStatus(checked as string, record)"
        ></Switch>
      </template>
    </template>
  </ProTable>
  <FormModal :items="items">
    <template #details>
      <FormItemRest>
        <div class="permission">
          <RadioGroup v-model:value="proOrDevice">
            <Radio value="1">项目</Radio>
            <Radio value="2">设备</Radio>
          </RadioGroup>
        </div>
        <div
          v-if="proOrDevice === '1'"
          style="display: flex; align-items: center"
        >
          <RadioGroup v-model:value="proOrDeviceALL">
            <Radio value="0">全部</Radio>
            <Radio value="1">自定义</Radio>
          </RadioGroup>
          <TreeSelect
            v-model:value="projectIdMuster"
            showCheckedStrategy="TreeSelect.SHOW_ALL"
            style="width: 250px"
            :tree-data="treeData"
            tree-checkable
            allow-clear
            placeholder="请选择"
            tree-node-filter-prop="label"
            :replaceFields="fieldNames"
            :maxTagCount="0"
            @change="changeSelectTree"
            :maxTagPlaceholder="maxTag"
          >
            <template #title="{ label, type }">
              <Tooltip>
                <template #title> {{ label }}</template>
                <div class="label">
                  <span style="color: #bababa" v-if="type == '1'">{{
                    label
                  }}</span>
                  <span v-else>{{ label }}</span>
                </div>
              </Tooltip>
            </template></TreeSelect
          >
        </div>
        <div v-if="proOrDevice === '2'">
          <b-button @click="onSelect">请点击选择</b-button>
          <div style="margin-top: 20px">
            当前选择设备个数:{{ selectedDeviceList.length || 0 }} 条
          </div>
        </div>
      </FormItemRest>
    </template>
  </FormModal>

  <FormModal2 :items="_items">
    <template #details>
      <FormItemRest>
        <div class="modal_table_only">
          <ProTable
            ref="tableRef"
            :fetchListApi="_getList"
            :columns="_columns"
            :row-selection="rowSelection"
            row-key="deviceId"
          >
          </ProTable>
        </div>
      </FormItemRest>
    </template>
  </FormModal2>
</template>

<script setup lang="tsx">
import { computed, ref } from 'vue';
import { hasPermission } from '@/permission';
import { useCommonStore } from '@/stores/modules';
import CustomTree from '@/views/statistical/components/customTree.vue';
import {
  Col,
  FormItemRest,
  Input,
  Modal,
  Radio,
  RadioGroup,
  Row,
  Switch,
  Tooltip,
  TreeSelect,
} from 'ant-design-vue';
import { cloneDeep, concat, pick } from 'lodash-es';
import { storeToRefs } from 'pinia';
import BButton from '@/components/Button';
import { ProFormProps } from '@/components/ProForm';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { useFormModal } from '@/hooks/formModal';
import {
  listToEnum,
  listToOption,
  treeToArray,
  treeToEnum,
} from '@/utils/utils';
import { getProjectData } from '@/api/config';
import {
  changeUserStatus,
  createUser,
  deleteUser,
  fetchGender,
  fetchPost,
  fetchSysNormalDisable,
  fetchUserStationPermission,
  fetchUsers,
  resetPass,
  updateUser,
  updateUserStationPermission,
} from '@/api/system';
import { getDeviceList, getInfo, relationUserDevice } from '@/api/user';
import DeptTree from './components/DeptTree.vue';
import { userStore } from './store';

const {
  refreshStore,
  deviceModeOptions,
  deviceModeEnum,
  getModelOptions,
  getModelEnum,
  projectList,
} = userStore();

const init = () => {
  refreshStore.getInfo();
};
init();
const fieldNames = {
  children: 'children',
  label: 'label',
  key: 'id',
  value: 'id',
};
const treeData = ref();
const countProjectNodes = (tree: any) => {
  let count = 0;
  tree.forEach((node: any) => {
    if (node.children && node.children.length > 0) {
      count += countProjectNodes(node.children);
    } else {
      count++;
    }
  });
  return count;
};
let projectDataAllNum = 0;
getProjectData().then((res: any) => {
  treeData.value = res.data;
  projectDataAllNum = countProjectNodes(res.data);
});

const maxTag = (omittedValues: any) => {
  if (omittedValues.length == 1) {
    return omittedValues[0].label;
  } else if (omittedValues.length == projectDataAllNum) {
    return '全部';
  } else {
    return '多项目';
  }
};
// 项目/设备
const proOrDevice = ref('1');
// 全部/自定义
const proOrDeviceALL = ref('0');
// 树结构
const projectIdMuster: any = ref([]);

const selectedDeviceList: any = ref([]);
const commonStore = useCommonStore();
const { departmentEnum, departmentTree } = storeToRefs(commonStore);
commonStore.fetchDepartment();

const sysNormalDisableOptions = ref<Global.Option[]>([]);
const sysNormalDisableEnum = ref<Record<string, any>>([]);
fetchSysNormalDisable().then((res) => {
  sysNormalDisableOptions.value = listToOption(
    res.data,
    'dictLabel',
    'dictValue',
  ) as Global.Option[];
  sysNormalDisableEnum.value = listToEnum(res.data, 'dictValue', 'dictLabel');
});

const ganderOptions = ref<Global.Option[]>([]);
fetchGender().then((res) => {
  ganderOptions.value = listToOption(
    res.data,
    'dictLabel',
    'dictValue',
  ) as Global.Option[];
});

const postOptions = ref<Global.Option[]>([]);
const roleOptions = ref<Global.Option[]>([]);
const updateUserClass = async (userId?: string | number) => {
  const res = await fetchPost(userId);
  // @ts-ignore
  postOptions.value = listToOption(res.posts, 'postName', 'postId');
  // @ts-ignore
  roleOptions.value = listToOption(res.roles, 'roleName', 'roleId');
  return res;
};

const fetchListApi = async (_params: any) => {
  const { createTime = [], ...params } = _params;
  if (createTime.length) {
    const [beginTime, endTime] = createTime;
    Object.assign(params, {
      params: { beginTime, endTime },
    });
  }
  return fetchUsers({
    ...params,
  });
};

const tableRef = ref();
const selectList: any = ref([]);
const rowSelection = computed<ProTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: selectList.value,
    onChange(values, selectedRows) {
      selectList.value = [...new Set(concat(values, selectList.value))];
    },
    onSelect(record, selected, selectedRows, nativeEvent) {
      if (selected) return;
      selectList.value = selectList.value.filter(
        (a: any) => a !== record.deviceId,
      );
    },
    onSelectAll(selected, selectedRows, changeRows) {
      if (selected) return;
      selectList.value = selectList.value.filter(
        (a: any) => !changeRows.find((b) => b.deviceId == a),
      );
    },
  };
});

const _columns = computed<ProTableProps['columns']>(() => [
  {
    title: '设备序列号',
    hideInTable: true,
    dataIndex: 'deviceCode',
  },
  {
    title: '设备序列号',
    hideInSearch: true,
    dataIndex: 'code',
  },
  {
    title: '固件版本',
    dataIndex: 'firmwareVersion',
  },
  {
    title: '',
    dataIndex: 'versionCode',
    hideInSearch: true,
    hideInTable: true,
  },
  {
    title: '软件版本',
    dataIndex: 'softwareVersion',
    width: 100,
    hideInSearch: true,
    customRender({ record, text }) {
      return `${record.softwareVersion || ''}${record.versionCode ? `(${record.versionCode})` : ''}`;
    },
  },
  {
    title: '软件版本',
    dataIndex: 'version',
    width: 100,
    hideInTable: true,
    customSearchRender(state) {
      return (
        <FormItemRest>
          <Row gutter={8}>
            <Col span={12}>
              <Input
                v-model:value={state.softwareVersion}
                placeholder='请输入软件版本'
              />
            </Col>
            <Col span={12}>
              <Input
                v-model:value={state.versionCode}
                placeholder='请输入编译版本'
              />
            </Col>
          </Row>
        </FormItemRest>
      );
    },
  },
  {
    title: '设备类型',
    dataIndex: 'deviceType',
    valueEnum: {
      ...deviceModeEnum.value,
    },
  },
  {
    title: '设备型号',
    dataIndex: 'modelId',
    hideInTable: true,
    valueEnum: {
      ...getModelEnum.value,
    },
  },
  {
    title: '项目名称',
    dataIndex: 'projectName',
    hideInSearch: true,
  },
  {
    title: '项目名称',
    dataIndex: 'projectId',
    hideInTable: true,
    customSearchRender(formState) {
      const onChangeForTree = (value: any) => {
        formState['projectId'] = value;
      };
      return (
        <CustomTree
          filed='projectId'
          formState={formState}
          data={treeData.value}
          onChange={onChangeForTree}
        ></CustomTree>
      );
    },
  },
  {
    title: '设备地址',
    dataIndex: 'address',
  },
]);
const deviceList: any = ref([]);
const editId = ref();
const _getList = async (params: any) => {
  params.userId = editId.value;
  const result = await getDeviceList(params);
  return result;
};
const columns = computed<ProTableProps['columns']>(() => [
  {
    title: '用户账号',
    dataIndex: 'userName',
    align: 'center',
  },
  {
    title: '用户昵称',
    dataIndex: 'nickName',
    align: 'center',
    hideInSearch: true,
  },
  {
    title: '部门',
    dataIndex: 'deptId',
    align: 'center',
    hideInSearch: true,
    valueEnum: {
      ...departmentEnum.value,
    },
  },
  {
    title: '手机号码',
    dataIndex: 'phonenumber',
    align: 'center',
  },
  {
    title: '状态',
    dataIndex: 'status',
    align: 'center',
    valueEnum: {
      ...sysNormalDisableEnum.value,
    },
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    align: 'center',
    isTime: true,
  },
  {
    title: '操作',
    dataIndex: 'operation',
    hideInSearch: true,
    align: 'center',
    fixed: 'right',
    width: 340,
  },
]);
const sleep = (cb) => {
  setTimeout(() => {
    cb();
  }, 500);
};

const onChangeStatus = (checked: string, record: any) => {
  const { userId, userName } = record;
  Modal.confirm({
    title: '系统提示',
    content: `确认要${checked === '1' ? '停用' : '启用'}${userName}用户吗？`,
    centered: true,
    onOk: async () => {
      await changeUserStatus({
        userId,
        status: checked as '1' | '0',
      });
      sleep(() => tableRef.value.refresh());
    },
  });
};
const { FormModal, open } = useFormModal({
  size: 'middle',
  column: 2,
});
const { FormModal: FormModal2, open: open2 } = useFormModal({
  size: 'large',
  formProps: {
    wrapperCol: { span: 24 },
  },
});

const _items = computed<ProFormProps['items']>(() => [
  {
    label: '',
    type: 'number',
    field: 'details',
  },
]);
const defaultPass = computed(() => VITE_DEFAULT_PASS);

const items = computed<ProFormProps['items']>(() =>
  [
    {
      label: '用户昵称',
      type: 'input',
      field: 'nickName',
      rules: [{ required: true, message: '请输入用户昵称', trigger: 'blur' }],
      props: {
        placeholder: '请输入用户名',
      },
    },
    {
      label: '归属部门',
      type: 'treeSelect',
      field: 'deptId',
      props: {
        treeData: departmentTree.value,
      },
    },
    {
      label: '手机号码',
      type: 'input',
      field: 'phonenumber',
      props: {},
    },
    {
      label: '邮箱',
      type: 'input',
      field: 'email',
      props: {},
    },
    {
      label: '用户账号',
      type: 'input',
      field: 'userName',
      hideInEdit: true,
      rules: [{ required: true, message: '请输入用户账号', trigger: 'blur' }],
      props: {
        autocomplete: 'off',
      },
    },
    {
      label: '用户密码',
      type: 'input',
      field: 'password',
      hideInEdit: true,
      rules: [{ required: true, message: '请输入密码', trigger: 'blur' }],
      props: {
        type: 'password',
        autocomplete: 'new-password',
      },
    },
    {
      label: '用户性别',
      type: 'select',
      field: 'sex',
      props: {
        options: ganderOptions.value,
      },
    },
    {
      label: '状态',
      type: 'radio',
      field: 'status',
      props: {
        options: sysNormalDisableOptions.value,
      },
    },
    {
      label: '岗位',
      type: 'select',
      field: 'postIds',
      props: {
        options: postOptions.value,
        mode: 'multiple',
      },
    },
    {
      label: '角色',
      type: 'select',
      field: 'roleIds',
      props: {
        options: roleOptions.value,
        mode: 'multiple',
      },
    },
    {
      label: '备注',
      type: 'textarea',
      field: 'remark',
      props: {
        rows: 5,
        showCount: true,
      },
    },
  ].filter((item) => item.hideInEdit !== isEdit.value),
);

const onAdd = async () => {
  isEdit.value = false;
  await updateUserClass();
  open({
    title: '新增用户',
    column: 2,
    size: 'middle',
    defaultValue: {
      userName: '',
      password: defaultPass.value,
      status: sysNormalDisableOptions.value[0].value,
    },
    serviceApi: async (params: any): Promise<any> => {
      await createUser(params);
      sleep(() => tableRef.value.refresh());
    },
  });
};

const isEdit = ref<boolean>(false);

const onEdit = async (record: any) => {
  const res = await updateUserClass(record.userId);
  isEdit.value = true;
  open({
    title: '编辑用户',
    column: 2,
    size: 'middle',
    defaultValue: {
      ...res.data,
      roleIds: res.roleIds,

      postIds: res.postIds,
    },
    serviceApi: async (params: any): Promise<any> => {
      await updateUser({
        ...params,
        userName: record.userName,
        userId: record.userId,
      });
      sleep(() => tableRef.value.refresh());
    },
  });
};

const omenStationEnum = ref({});
const userReladata = ref([]);
const onSetDataPermission = async (record: any) => {
  // const details = await updateUserClass(record.userId);
  // console.log(details.data, 'data');

  const { userId, userName } = record;
  editId.value = userId;
  const res: any = await getInfo(userId);
  const { data } = res;
  proOrDeviceALL.value = data.projectIds === 'all' ? '0' : '1';
  // treeDatatreeDatatreeData
  // 项目回显
  if (data.projectIds === 'all') {
    const Enum = treeToEnum(treeData.value, {
      label: 'label',
      value: 'id',
    });
    projectIdMuster.value = Object.keys(Enum).map((i) => Number(i));
  } else {
    projectIdMuster.value = data.projectIds
      ? data.projectIds.split(',').map((i: any) => Number(i))
      : [];
  }
  const params = {
    pageNum: 1,
    pageSize: 9999,
    userId,
  };
  const result = await getDeviceList(params);
  deviceList.value = result.rows;
  userReladata.value = [];
  for (let i in deviceList.value) {
    if (deviceList.value[i].isCheck == 1) {
      userReladata.value.push(deviceList.value[i]);
    }
  }
  if (userReladata.value.length) {
    selectedDeviceList.value = userReladata.value.map((i: any) => i.deviceId);
  } else {
    selectedDeviceList.value = [];
  }
  open({
    title: '数据权限',
    defaultValue: {
      ...record,
    },
    size: 'small',
    column: 1,
    // hasEditPermission: hasPermission('userStation:update'),
    items: [
      {
        label: '数据权限',
        type: 'input',
        field: 'details',
      },
    ],
    serviceApi: async (params: any) => {
      await relationUserDevice({
        deviceIds: selectedDeviceList.value.join(),
        userName: userName,
      });
      params.projectIds = projectIdMuster.value.join();
      if (proOrDeviceALL.value == '0') params.projectIds = 'all';
      const _params1 = pick(res, ['roleIds', 'roles', 'postIds', 'posts']);
      const queryParams = { ...params, ..._params1 };
      await updateUser(queryParams);
    },
  });
};

const changeSelectTree = (label: any) => {
  const Enum = treeToEnum(treeData.value, {
    label: 'label',
    value: 'id',
  });
  proOrDeviceALL.value = Object.values(Enum).length == label.length ? '0' : '1';
};
const onSelect = () => {
  selectList.value = cloneDeep(selectedDeviceList.value);
  open2({
    title: '设备列表',
    modalType: 'add',
    serviceApi: async (params) => {
      selectedDeviceList.value = selectList.value;
    },
  });
};
const onDelete = async (record: any) => {
  const { userName, userId } = record;
  Modal.confirm({
    title: '系统提示',
    content: `确认要删除${userName}用户吗？`,
    centered: true,
    onOk: async () => {
      await deleteUser(userId);
      sleep(() => tableRef.value.refresh());
    },
  });
};

const onResetPassword = async (record: any) => {
  const { userName, userId } = record;
  open({
    title: '提示',
    content: `请输入${userName}的新密码`,
    size: 'mini',
    column: 1,
    defaultValue: {},
    items: [
      {
        type: 'input',
        field: 'password',
        wrapperCol: { span: 24 },
        rules: [{ required: true, message: '请输入新密码' }],
        props: {
          placeholder: '请输入新密码',
        },
      },
    ],
    serviceApi: async function (params: any): Promise<any> {
      await resetPass({
        ...params,
        userId,
      });
    },
  });
};
</script>

<style scoped lang="scss">
.permission {
  margin-bottom: 20px;
}
.label {
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:deep(.ant-select-selection-overflow-item) {
  max-width: 49% !important;
  margin-right: 4px !important;
}
</style>
